package com.hst.capacity.domain.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.smartravel.framework.redis.LockRedis;
import cn.smartravel.traffic.alitrip.AlitripCarOpen;
import com.alibaba.fastjson2.JSON;
import com.hst.capacity.application.biz.SmsBiz;
import com.hst.capacity.domain.common.constants.AliTripTransferConstants;
import com.hst.capacity.domain.common.constants.Constants;
import com.hst.capacity.domain.exception.BusinessException;
import com.hst.capacity.domain.model.entity.order.dispatch.ExpatriateDriverRecordEntity;
import com.hst.capacity.domain.model.entity.order.intercity.IntercityOrderEntity;
import com.hst.capacity.domain.model.entity.order.pool.OrderPoolEntity;
import com.hst.capacity.domain.model.request.dispatch.DispatchPartyDriverParam;
import com.hst.capacity.domain.model.request.specialcar.SpListParam;
import com.hst.capacity.domain.model.response.PagingResultVO;
import com.hst.capacity.domain.model.response.driver.DriverInfoVO;
import com.hst.capacity.domain.model.response.order.OrderPoolVO;
import com.hst.capacity.domain.model.response.order.OrderVO;
import com.hst.capacity.domain.repository.redis.CacheRedis;
import com.hst.capacity.domain.service.OrderPoolService;
import com.hst.capacity.infra.convertor.DriverConvertor;
import com.hst.capacity.infra.convertor.IntercityConvertor;
import com.hst.capacity.infra.convertor.OrderPoolConvertor;
import com.hst.capacity.infra.persistence.jpa.order.dispatch.ExpatriateDriverRecordRepoitory;
import com.hst.capacity.infra.persistence.jpa.order.pool.OrderPoolRepository;
import com.hst.capacity.infra.util.DateUtil;
import com.hst.capacity.infra.util.StringUtil;
import com.taobao.api.request.AlitripCarOrderConfirmRequest;
import com.taobao.api.response.AlitripCarOrderConfirmResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

@Service
public class OrderPoolServiceImpl implements OrderPoolService {

    @Autowired
    OrderPoolRepository orderRepository;

    @Autowired
    AlitripCarOpen alitripCarOpen;

    @Autowired
    LockRedis lockRedis;

    @Autowired
    CacheRedis cacheRedis;

    @Autowired
    ExpatriateDriverRecordRepoitory expatriateDriverRecordRepoitory;

    @Autowired
    SmsBiz smsBiz;

    /**
     * 分页并条件查询今日专车信息
     * @param param
     * @return
     */
    @Override
    public PagingResultVO<OrderPoolEntity> searchWithConditionsAndPaging(SpListParam param) {
        Page<OrderPoolEntity> page = orderRepository.findAll(new Specification<OrderPoolEntity>() {
            @Override
            public Predicate toPredicate(Root<OrderPoolEntity> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                // 定义条件LIST
                List<Predicate> predicates = new ArrayList<Predicate>();
                //idFranchisee
                if (ObjectUtil.isNotEmpty(param.getIdFranchisee())) {
                    predicates.add(criteriaBuilder.equal(root.get("idFranchisee"),param.getIdFranchisee()));
                }
                //status
                if (StrUtil.isNotEmpty(param.getOrderStatus())) {
                    List<Integer> strings = Convert.toList(Integer.class, param.getOrderStatus());
                    CriteriaBuilder.In<Integer> in = criteriaBuilder.in(root.get("status"));
                    for (Integer v:strings) {
                        in.value(v);
                    }
                    predicates.add(criteriaBuilder.and(in));
                }
                //orderSource
                if (StrUtil.isNotEmpty(param.getOrderSources())) {
                    List<Integer> strings = Convert.toList(Integer.class, param.getOrderSources());
                    CriteriaBuilder.In<Integer> in = criteriaBuilder.in(root.get("orderSource"));
                    for (Integer v:strings) {
                        in.value(v);
                    }
                    predicates.add(criteriaBuilder.and(in));
                }
                //paymentStatus
                if (StrUtil.isNotEmpty(param.getPayStatus())) {
                    List<Integer> strings = Convert.toList(Integer.class, param.getPayStatus());
                    CriteriaBuilder.In<Integer> in = criteriaBuilder.in(root.get("paymentStatus"));
                    for (Integer v:strings) {
                        in.value(v);
                    }
                    predicates.add(criteriaBuilder.and(in));
                }
//                //regionCode 城际原表中没有regionCode
//                if (StrUtil.isNotEmpty(param.getRegionCodes())) {
//                    List<Integer> strings = Convert.toList(Integer.class, param.getRegionCodes());
//                    CriteriaBuilder.In<Integer> in = criteriaBuilder.in(root.get("regionCode"));
//                    for (Integer v:strings) {
//                        in.value(v);
//                    }
//                    predicates.add(criteriaBuilder.and(in));
//                }


                //排序
                query.orderBy(criteriaBuilder.desc(root.get("createTime")));
                Predicate[] array = predicates.toArray(new Predicate[0]);
                return criteriaBuilder.and(array);
            }
        }, PageRequest.of(param.getPageIndex() - 1, param.getPageSize()));
        return new PagingResultVO(page.getTotalElements(),page.getContent());
    }

    @Override
    public OrderPoolEntity orderPoolInfo(String idExternalOrder) {
        OrderPoolEntity entity = orderRepository.findByExternalOrderId(idExternalOrder);
        if (entity == null)
            throw new BusinessException(5002,"订单号不存在请检查");
        return entity;
    }

    @Override
    public OrderVO virtualAcceptOrder(String idOrder, String idDriver, String driverInfo) {
        OrderPoolEntity order = orderRepository.findByIdOrder(idOrder);
        if (order == null)
            throw new BusinessException(5002,"未找到此订单请核查");

        if (order.getStatus() > Constants.OrderStatus.ORDER_STATUS_ACCEPTED) {
            throw new BusinessException(5002, "订单已开始服务，无法虚拟接单。");
        } else if (order.getStatus() == Constants.OrderStatus.ORDER_STATUS_ACCEPTED &&
                StringUtil.isNotBlank(order.getIdDriver())) {
            if (order.getVirtualOrderAccepted() == 1) {
                return OrderPoolConvertor.INSTANCE.convert2VO(order);
            } else {
                throw new BusinessException(5002, "订单已安排司机，如需更换司机请执行改派才做。");
            }
        }

        if (order.getStatus() < Constants.OrderStatus.ORDER_STATUS_ACCEPTED)
            order.setStatus(Constants.OrderStatus.ORDER_STATUS_ACCEPTED);
        order.setIdDriver(idDriver);
        order.setVirtualOrderAccepted(1);
        order.setDriverInfo(driverInfo);

        return OrderPoolConvertor.INSTANCE.convert2VO(orderRepository.saveAndFlush(order));
    }

    @Override
    public OrderVO virtualAcceptOrder(OrderPoolEntity order, String idDriver, String driverInfo) {
        if (order.getStatus() > Constants.OrderStatus.ORDER_STATUS_ACCEPTED)
            throw new BusinessException(5002,"订单已开始服务，无法虚拟接单。");

        if (order.getStatus() == Constants.OrderStatus.ORDER_STATUS_ACCEPTED &&
                StringUtil.isNotBlank(order.getIdDriver())) {
            if (order.getVirtualOrderAccepted() == 1) {
                return OrderPoolConvertor.INSTANCE.convert2VO(order);
            } else {
                throw new BusinessException(5002, "订单已安排司机，如需更换司机请执行改派才做。");
            }
        }

        if (order.getStatus() < Constants.OrderStatus.ORDER_STATUS_ACCEPTED)
            order.setStatus(Constants.OrderStatus.ORDER_STATUS_ACCEPTED);
        order.setIdDriver(idDriver);
        order.setVirtualOrderAccepted(1);
        order.setDriverInfo(driverInfo);

        return OrderPoolConvertor.INSTANCE.convert2VO(orderRepository.saveAndFlush(order));
    }

    @Override
    public boolean dispatchPartyDriver(DispatchPartyDriverParam param) {

        OrderPoolEntity order = orderRepository.findByIdOrder(param.getIdOrder());
        if (order == null)
            throw new BusinessException(5002, "订单不存在，请检查参数idOrder是否正确");

        if (order.getOrderSource() == Constants.OrderSource.ALITRIP) {

            long confirmType = 0L;
            if (StringUtil.isNotBlank(order.getIdOrder()))
                confirmType = 1L;

            /**
             * 改派司机接口：
             */
            AlitripCarOrderConfirmRequest.OrderConfirm orderConfirm = new AlitripCarOrderConfirmRequest.OrderConfirm();
            //JSON.toJSONString(orderConfirm);
            orderConfirm.setConfirmTime(DateUtil.getNowLocalDate());
            //0应答 1改派
            orderConfirm.setConfirmType(confirmType);
            orderConfirm.setOrderId(order.getExternalOrderId());
            orderConfirm.setProviderId(AliTripTransferConstants.ProviderIdWithMemberID.get(order.getIdMember()));
            orderConfirm.setThirdOrderId(param.getIdOrder());
            //0:接送机 1：实时打车 2：租车(不传值默认为0)
            orderConfirm.setUseType(0L);
            //车辆描述,车辆颜色,候车地点等：红色,T3出口
//                String carDesc = String.format("%s,%s",param.getVehicleColor(),"黄花机场T1");
//                orderConfirm.setDriverCarDesc(carDesc);
            //司机车型名称:奔驰C200
            String carName = String.format("%s%s", param.getBrand(), param.getModel());
            orderConfirm.setDriverCarName(carName);
            //司机车牌号:浙A111111
            orderConfirm.setDriverCarNo(param.getPlateNumber());
            orderConfirm.setDriverName(param.getDriverName());
            orderConfirm.setDriverCarColor(param.getColor());
            orderConfirm.setCarBrand(param.getBrand());
            orderConfirm.setCarModel(param.getModel());
            //司机联系方式。格式：加号+国家区号+空格+当地电话号码 +86 13266365287
            String tel = param.getMobile();
            if (!tel.contains("+86"))
                tel = String.format("+86 %s", tel);
            orderConfirm.setDriverTel(tel);
//                //车龄
//                orderConfirm.setCarAge();
//                //司机性别
//                orderConfirm.setDeriverGender();
            //司机图片，公网可访问链接
//                orderConfirm.setDriverPic();
//                orderConfirm.setCarPic();

//                log.info("orderConfirm:" + JSON.toJSONString(orderConfirm));

            String tenant = AliTripTransferConstants.MemberIDFindMerchant.get(order.getIdMember());
            AlitripCarOrderConfirmResponse res = alitripCarOpen.orderConfirm(orderConfirm, tenant);
//                log.info("data:" + res.getData());
//                log.info("message:" + res.getMessage());
//                log.info("messageCode:" + res.getMessageCode());
            if (res == null || res.getMessage() == null
                    || !(res.getMessage().equals("成功") || res.getMessage().toLowerCase(Locale.ROOT).equals("ok"))) {
                lockRedis.clearValue(param.getIdOrder());
                throw new BusinessException(5002, "飞猪接口回调失败，请重新执行");
            }

        } else if (order.getOrderSource() == Constants.OrderSource.XIAODUO ) {


        }

        //指定司机
        //给外派司机发短信
        smsBiz.sendDispacthOrderSms(param.getMobile(), order.getAppointmentTime(), order.getIdVehicleType(), order.getFlightNo(), order.getPassengerMobile(), order.getIdMember());

        //加盟商指定自有司机账户
        String idThirdPartyDriver = AliTripTransferConstants.AliTrip_ThirdPartyDriver.get(order.getIdFranchisee());
        if (StringUtil.isBlank(idThirdPartyDriver))
            idThirdPartyDriver = order.getIdFranchisee();
        order.setIdDriver(idThirdPartyDriver);
        order.setDriverInfo(param.getDriverName()+"/"+param.getMobile());
        order.setVirtualOrderAccepted(0);
        order.setStatus(Constants.OrderStatus.ORDER_STATUS_ACCEPTED);
        orderRepository.save(order);

        //外调记录
        ExpatriateDriverRecordEntity recordEntity = expatriateDriverRecordRepoitory.findByIdOrderAndDriverMobile(param.getIdOrder(),param.getMobile());
        if (recordEntity == null)
            recordEntity = new ExpatriateDriverRecordEntity();

        recordEntity.setIdOrder(param.getIdOrder());
        recordEntity.setDriverMobile(param.getMobile());
        recordEntity.setDriverName(param.getDriverName());
        recordEntity.setPlateNumber(param.getPlateNumber());
        recordEntity.setBrand(param.getBrand());
        recordEntity.setColor(param.getColor());
        recordEntity.setModel(param.getModel());
        if (StringUtil.isNotBlank(order.getExternalOrderId()))
            recordEntity.setExternalOrderId(order.getExternalOrderId());
        recordEntity.setMemo("外派渠道"+order.getOrderSource());
        expatriateDriverRecordRepoitory.save(recordEntity);

        if (StringUtil.isNotBlank(order.getExternalOrderId())) {
            DriverInfoVO driverInfoVO = DriverConvertor.INSTANCE.convert2Info(param);
            cacheRedis.writePartyDriverValue(order.getIdOrder(), JSON.toJSONString(driverInfoVO));
        }

        return true;
    }

    @Override
    public OrderVO findOrderByIdOrder(String idOrder) {
        OrderPoolEntity order = orderRepository.getById(idOrder);
        if (order == null)
            throw new BusinessException(5002, "订单不存在，请检查参数idOrder是否正确");

        return OrderPoolConvertor.INSTANCE.convert2VO(order);
    }

}
